<!-- uniapp vue3 markdown解析 -->
<template>
  <view class="ua__markdown"
    ><rich-text
      user-select
      space="nbsp"
      :nodes="val"
      @itemclick="handleItemClick"
    ></rich-text
  ></view>
</template>

<script setup>
import { ref, computed } from "vue";
import MarkdownIt from "./lib/markdown-it.min.js";
import hljs from "./lib/highlight/uni-highlight.min.js";
import "./lib/highlight/atom-one-dark.css";
import parseHtml from "./lib/html-parser.js";
const props = defineProps({
  // 解析内容
  source: { type: [Object, String], default: "" },
  fn: {
    type: Function,
    default: () => {},
  },
  showLine: { type: [Boolean, String], default: true },
});

let copyCodeData = [];
const markdown = MarkdownIt({
  html: true,
  //   highlight: function (str, lang) {
  //     let preCode = "";
  //     try {
  //       preCode = hljs.highlightAuto(str).value;
  //     } catch (err) {
  //       preCode = markdown.utils.escapeHtml(str);
  //     }
  //     const lines = preCode.split(/\n/).slice(0, -1);
  //     // 添加自定义行号
  //     let html = lines
  //       .map((item, index) => {
  //         if (item == "") {
  //           return "";
  //         }
  //         return (
  //           '<li><span class="line-num" data-line="' +
  //           (index + 1) +
  //           '"></span>' +
  //           item +
  //           "</li>"
  //         );
  //       })
  //       .join("");
  //     if (props.showLine) {
  //       html = '<ol style="padding: 0px 30px;">' + html + "</ol>";
  //     } else {
  //       html = '<ol style="padding: 0px 7px;list-style:none;">' + html + "</ol>";
  //     }
  //     copyCodeData.push(str);
  //     let htmlCode = `<div class="markdown-wrap">`;
  //     // #ifndef MP-WEIXIN
  //     htmlCode += `<div style="color: #aaa;text-align: right;font-size: 12px;padding:8px;">`;
  //     htmlCode += `${lang}<a class="copy-btn" code-data-index="${
  //       copyCodeData.length - 1
  //     }" style="margin-left: 8px;">复制代码</a>`;
  //     htmlCode += `</div>`;
  //     // #endif
  //     htmlCode += `<pre class="hljs" style="padding:10px 8px 0;margin-bottom:5px;overflow: auto;display: block;border-radius: 5px;"><code>${html}</code></pre>`;
  //     htmlCode += "</div>";
  //     return htmlCode;
  //   },
});

const val = computed(() => {
  return parseNodes(props.fn(props.source));
});

const parseNodes = (value) => {
  if (!value) return;
  // 解析<br />到\n
  value = value.replace(/<br>|<br\/>|<br \/>/g, "\n");
  value = value.replace(/&nbsp;/g, " ");
  let htmlString = "";
  if (value.split("```").length % 2) {
    let mdtext = value;
    if (mdtext[mdtext.length - 1] != "\n") {
      mdtext += "\n";
    }
    htmlString = markdown.render(mdtext);
  } else {
    htmlString = markdown.render(value);
  }
  // 解决小程序表格边框型失效问题
  htmlString = htmlString.replace(/<table/g, `<table class="table"`);
  htmlString = htmlString.replace(/<tr/g, `<tr class="tr"`);
  htmlString = htmlString.replace(/<th>/g, `<th class="th">`);
  htmlString = htmlString.replace(/<td/g, `<td class="td"`);
  htmlString = htmlString.replace(/<hr>|<hr\/>|<hr \/>/g, `<hr class="hr">`);

  htmlString = htmlString.replace(/<ol/g, `<ol class="custom-ol"`);
  htmlString = htmlString.replace(/<ul/g, `<ul class="custom-ul"`);
  htmlString = htmlString.replace(/<li/g, `<li class="custom-li"`);
  // console.log("test---------");

  // #ifndef APP-NVUE
  return htmlString;
  // #endif

  // 将htmlString转成htmlArray，反之使用rich-text解析
  // #ifdef APP-NVUE
  return parseHtml(htmlString);
  // #endif
};

// 复制代码
const handleItemClick = (e) => {
  let { attrs } = e.detail.node;
  let { "code-data-index": codeDataIndex, class: className } = attrs;
  if (className == "copy-btn") {
    uni.setClipboardData({
      data: copyCodeData[codeDataIndex],
      showToast: false,
      success() {
        uni.showToast({
          title: "复制成功",
          icon: "none",
        });
      },
    });
  }
};
</script>

<style lang="scss" scoped>
// .ua__markdown {
//   font-size: 14px;
//   line-height: 1.5;
//   word-break: break-all;
//   h1,
//   h2,
//   h3,
//   h4,
//   h5,
//   h6 {
//     font-family: inherit;
//     font-weight: 500;
//     line-height: 1.1;
//     color: inherit;
//   }
//   h1,
//   h2,
//   h3 {
//     margin-top: 20px;
//     margin-bottom: 10px;
//   }
//   h4,
//   h5,
//   h6 {
//     margin-top: 10px;
//     margin-bottom: 10px;
//   }
//   .h1,
//   h1 {
//     font-size: 36px;
//   }
//   .h2,
//   h2 {
//     font-size: 30px;
//   }
//   .h3,
//   h3 {
//     font-size: 24px;
//   }
//   .h4,
//   h4 {
//     font-size: 18px;
//   }
//   .h5,
//   h5 {
//     font-size: 14px;
//   }
//   .h6,
//   h6 {
//     font-size: 12px;
//   }
//   a {
//     background-color: transparent;
//     color: #2196f3;
//     text-decoration: none;
//   }
//   hr,
//   ::v-deep .hr {
//     margin-top: 20px;
//     margin-bottom: 20px;
//     border: 0;
//     border-top: 1px solid #e5e5e5;
//   }
//   img {
//     max-width: 35%;
//   }
//   p {
//     margin: 0 0 10px;
//   }
//   em {
//     font-style: italic;
//     font-weight: inherit;
//   }
//   ol,
//   ul {
//     margin-top: 0;
//     margin-bottom: 10px;
//     // padding-left: 40px;
//   }
//   ol ol,
//   ol ul,
//   ul ol,
//   ul ul {
//     margin-bottom: 0;
//   }
//   ol ol,
//   ul ol {
//     list-style-type: lower-roman;
//   }
//   ol ol ol,
//   ul ul ol {
//     list-style-type: lower-alpha;
//   }
//   dl {
//     margin-top: 0;
//     margin-bottom: 20px;
//   }
//   dt {
//     font-weight: 600;
//   }
//   dt,
//   dd {
//     line-height: 1.4;
//   }
//   .task-list-item {
//     list-style-type: none;
//   }
//   .task-list-item input {
//     margin: 0 0.2em 0.25em -1.6em;
//     vertical-align: middle;
//   }
//   pre {
//     position: relative;
//     z-index: 11;
//   }
//   code,
//   kbd,
//   pre,
//   samp {
//     font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
//   }
//   code:not(.hljs) {
//     padding: 2px 4px;
//     font-size: 90%;
//     color: #c7254e;
//     background-color: #ffe7ee;
//     border-radius: 4px;
//   }
//   code:empty {
//     display: none;
//   }
//   pre code.hljs {
//     color: var(--vg__text-1);
//     border-radius: 16px;
//     background: var(--vg__bg-1);
//     font-size: 12px;
//   }
//   .markdown-wrap {
//     font-size: 12px;
//     margin-bottom: 10px;
//   }
//   pre.code-block-wrapper {
//     background: #2b2b2b;
//     color: #f8f8f2;
//     border-radius: 4px;
//     overflow-x: auto;
//     padding: 1em;
//     position: relative;
//   }
//   pre.code-block-wrapper code {
//     padding: auto;
//     font-size: inherit;
//     color: inherit;
//     background-color: inherit;
//     border-radius: 0;
//   }
//   .code-block-header__copy {
//     font-size: 16px;
//     margin-left: 5px;
//   }
//   abbr[data-original-title],
//   abbr[title] {
//     cursor: help;
//     border-bottom: 1px dotted #777;
//   }
//   blockquote {
//     padding: 10px 20px;
//     margin: 0 0 20px;
//     font-size: 17.5px;
//     border-left: 5px solid #e5e5e5;
//   }
//   blockquote ol:last-child,
//   blockquote p:last-child,
//   blockquote ul:last-child {
//     margin-bottom: 0;
//   }
//   blockquote .small,
//   blockquote footer,
//   blockquote small {
//     display: block;
//     font-size: 80%;
//     line-height: 1.42857143;
//     color: #777;
//   }
//   blockquote .small:before,
//   blockquote footer:before,
//   blockquote small:before {
//     content: "\2014 \00A0";
//   }
//   .blockquote-reverse,
//   blockquote.pull-right {
//     padding-right: 15px;
//     padding-left: 0;
//     text-align: right;
//     border-right: 5px solid #eee;
//     border-left: 0;
//   }
//   .blockquote-reverse .small:before,
//   .blockquote-reverse footer:before,
//   .blockquote-reverse small:before,
//   blockquote.pull-right .small:before,
//   blockquote.pull-right footer:before,
//   blockquote.pull-right small:before {
//     content: "";
//   }
//   .blockquote-reverse .small:after,
//   .blockquote-reverse footer:after,
//   .blockquote-reverse small:after,
//   blockquote.pull-right .small:after,
//   blockquote.pull-right footer:after,
//   blockquote.pull-right small:after {
//     content: "\00A0 \2014";
//   }
//   .footnotes {
//     -moz-column-count: 2;
//     -webkit-column-count: 2;
//     column-count: 2;
//   }
//   .footnotes-list {
//     padding-left: 2em;
//   }
//   table,
//   ::v-deep .table {
//     border-spacing: 0;
//     border-collapse: collapse;
//     width: 100%;
//     max-width: 65em;
//     overflow: auto;
//     margin-top: 0;
//     margin-bottom: 16px;
//   }
//   table tr,
//   ::v-deep .table .tr {
//     border-top: 1px solid #e5e5e5;
//   }
//   table th,
//   table td,
//   ::v-deep .table .th,
//   ::v-deep .table .td {
//     padding: 6px 13px;
//     border: 1px solid #e5e5e5;
//   }
//   table th,
//   ::v-deep .table .th {
//     font-weight: 600;
//     background-color: #eee;
//   }
//   .hljs[class*="language-"]:before {
//     position: absolute;
//     z-index: 3;
//     top: 0.8em;
//     right: 1em;
//     font-size: 0.8em;
//     color: #999;
//   }
//   .hljs[class~="language-js"]:before {
//     content: "js";
//   }
//   .hljs[class~="language-ts"]:before {
//     content: "ts";
//   }
//   .hljs[class~="language-html"]:before {
//     content: "html";
//   }
//   .hljs[class~="language-md"]:before {
//     content: "md";
//   }
//   .hljs[class~="language-vue"]:before {
//     content: "vue";
//   }
//   .hljs[class~="language-css"]:before {
//     content: "css";
//   }
//   .hljs[class~="language-sass"]:before {
//     content: "sass";
//   }
//   .hljs[class~="language-scss"]:before {
//     content: "scss";
//   }
//   .hljs[class~="language-less"]:before {
//     content: "less";
//   }
//   .hljs[class~="language-stylus"]:before {
//     content: "stylus";
//   }
//   .hljs[class~="language-go"]:before {
//     content: "go";
//   }
//   .hljs[class~="language-java"]:before {
//     content: "java";
//   }
//   .hljs[class~="language-c"]:before {
//     content: "c";
//   }
//   .hljs[class~="language-sh"]:before {
//     content: "sh";
//   }
//   .hljs[class~="language-yaml"]:before {
//     content: "yaml";
//   }
//   .hljs[class~="language-py"]:before {
//     content: "py";
//   }
//   .hljs[class~="language-docker"]:before {
//     content: "docker";
//   }
//   .hljs[class~="language-dockerfile"]:before {
//     content: "dockerfile";
//   }
//   .hljs[class~="language-makefile"]:before {
//     content: "makefile";
//   }
//   .hljs[class~="language-javascript"]:before {
//     content: "js";
//   }
//   .hljs[class~="language-typescript"]:before {
//     content: "ts";
//   }
//   .hljs[class~="language-markup"]:before {
//     content: "html";
//   }
//   .hljs[class~="language-markdown"]:before {
//     content: "md";
//   }
//   .hljs[class~="language-json"]:before {
//     content: "json";
//   }
//   .hljs[class~="language-ruby"]:before {
//     content: "rb";
//   }
//   .hljs[class~="language-python"]:before {
//     content: "py";
//   }
//   .hljs[class~="language-bash"]:before {
//     content: "sh";
//   }
//   .hljs[class~="language-php"]:before {
//     content: "php";
//   }
// }
</style>

<style lang="scss">
.chat-message {
  // max-width: 500px;
  font-size: 26px;
  color: #192236;
  padding: 16px;
  word-wrap: break-word;
  background-color: #fff;
  border-radius: 0 16px 16px 16px;
  margin: 0;
  line-height: 40px;
  //   * {
  //     font-size: 26px;
  //     margin-block-start: 0;
  //     margin-block-end: 0;
  //   }
}
.cursor-blink {
  display: inline-block;
  width: 8rpx;
  height: 24rpx;
  position: relative;
  font-weight: 600;
  animation: blink-animation 1s linear infinite;
  &::after {
    content: "";
    position: absolute;
    width: 2rpx;
    height: 30rpx;
    background-color: #192236;
    left: 0;
    top: 0;
  }
}

@keyframes blink-animation {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
.ua__markdown {
  ol {
    list-style: decimal;
    margin: 0;
    padding: 0;
    // padding-left: 32rpx;
  }
  ul {
    list-style: none;
    list-style-type: none;
    padding-left: 0;
  }
  li {
    list-style: none;
    list-style-type: none;
    padding-left: 0;
  }
  ul::before,
  ul::after {
    display: none;
  }
  p,
  li,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    // list-style: none !important;
    margin-bottom: 16rpx;
    font-size: 26rpx !important;
  }
  p:last-child {
    margin-bottom: 0;
  }

  .custom-ul {
    padding-left: 0;
    margin-left: 25rpx;
  }
  .custom-ol {
    padding-left: 0;
    margin-left: 25rpx;
  }
  .custom-li {
    padding-left: 0;
    margin-left: 25rpx;
  }

  pre,
  code {
    white-space: pre-line;
  }
}
</style>
